package com.flybutter.usagelab.utils

import android.app.Activity
import android.app.usage.UsageStats
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.util.TypedValue
import java.lang.IllegalArgumentException
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

var defaultIcon: Drawable? = null

var iconMap = mutableMapOf<String,Drawable>()
    private set
var nameMap = mutableMapOf<String,String>()
    private set

val executorService: ExecutorService by lazy {
    return@lazy Executors.newFixedThreadPool(3)
}

fun Context.getAppName(packageName: String,handler: (String)->Unit): String{
    executorService.submit {
        handler(getAppName(packageName))
    }
    return ""
}

fun Context.getAppName(packageName: String): String{
    var name = nameMap[packageName]
    if (name == null){
        name = packageManager.findPackageInfo(packageName)?.applicationInfo?.loadLabel(this.packageManager).toString()
        nameMap[packageName] = name
    }
    return name
}

fun Context.getAppIcon(packageName: String,handler: (Drawable)->Unit): Drawable{
    executorService.submit {
        handler(getAppIcon(packageName))
    }
    return getAppIcon(this.packageName)
}

fun Context.getAppIcon(packageName: String): Drawable{
    val pm = packageManager
    var icon = iconMap[packageName]
    if (icon == null){
        icon = pm.findPackageInfo(packageName)?.applicationInfo?.loadIcon(pm)
        if (icon == null){
            if (defaultIcon == null){
                defaultIcon = this.getAppIcon(this.packageName)
            }
            return defaultIcon!!
        }
        iconMap[packageName] = icon
    }
    return icon
}


fun PackageManager.findPackageInfo(packageName: String): PackageInfo?{
    val list = getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES)
    val p = getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES)
        .firstOrNull{ it.packageName == packageName }
    return getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES)
        .firstOrNull{ it.packageName == packageName }
}

fun Context.getInstalledPackage(excludeSys: Boolean = true): List<PackageInfo>{
    return packageManager.getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES)
        .filter { !excludeSys || ((it.applicationInfo.flags and 1) == 0) }
}

fun Context.dpToPixel(dp: Float): Float{
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,resources.displayMetrics)
}

fun <T> UsageStats.getFiled(name: String): T?{
    val cla = this::class.java
    val filed = cla.declaredFields.find {
        it.name == name
    }
    if (filed != null){
        filed.isAccessible = true
        return filed.get(this) as T?
    }
    var methodName = name
    if (methodName.startsWith("m"))
        methodName = methodName.substring(1)
    methodName = "get" + methodName.substring(0,1).uppercase() + methodName.substring(1)
    return cla.getMethod(methodName).invoke(this) as T?
}